package com.matt.controller;

import com.dotflat.fin.cnst.Const;
import com.dotflat.fin.domain.FinPlanOrder;
import com.dotflat.fin.service.FinPlanOrderService;
import com.dotflat.fin.service.WechatPayService;
import com.dotflat.fin.utils.PaymentUtils;
import com.dotflat.fin.utils.excelUtil.StringUtils;
import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest;
import com.matt.commons.exception.BusinessException;
import com.matt.commons.model.StatusResponse;
import com.matt.domain.Clientele;
import com.matt.foundation.model.ErrorCode;
import com.matt.service.ClienteleService;
import com.matt.service.ContractService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

import static org.springframework.web.bind.annotation.RequestMethod.POST;

/**
 * Filename: WeixinAppPay.java <br>
 *
 * Description: 微信APP支付<br>
 *
 * @author: lenovo <br>
 * @version: 1.0 <br>
 * @Createtime: 2020-11-01 <br>
 *
 * Modification History:
 * Date         Author          Version            Description
 *---------------------------------------------------------*
 * 2019-12-01      lenovo            v1.0              第一次创建
 *
 * @Copyright: Copyright (c)2019 by lenovo <br>
 *
 */
@Slf4j
@RestController
@RequestMapping("/other_system/pay/wx")
@Api(tags = "其他系统 - 微信支付")
public class OtherSystemPayWechatController {


    @Autowired
    private WechatPayService wechatPayService;

//    @Autowired
//    WxPayService wxPayService;

    @Autowired
    FinPlanOrderService finPlanOrderService;

    @Autowired
    ContractService contractService;

    @Autowired
    ClienteleService clienteleService;


    @ApiOperation("公众号拉起支付")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "ticket", value = "票据", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "resourceType", required = true, value = "资源类型，0充值，1收费单", dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "resourceId", value = "通常是收费单id", dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "openId", value = "公众号openid，公众号/小程序支付逻辑请填写", dataType = "string")
    })
    @RequestMapping(value = "/prepare",method = POST)
    public Object getWxOrder(@RequestParam(defaultValue = "1") int resourceType,
                             @RequestParam String clienteleId,
                             @RequestParam String resourceId,
                             @RequestParam(required = false) String openId,
                             @RequestParam(defaultValue = "0") int useDeposit)
    {
        Const.RES_TYPE resType = Const.RES_TYPE.get(resourceType);

        Clientele clientele = null;
        Map result = null;

        if (resType == Const.RES_TYPE.PRODUCT){
            FinPlanOrder order = finPlanOrderService.get(resourceId);

            if (order == null){
                throw new BusinessException(ErrorCode.MATERIAL_NOT_EXIST, "账单不存在");
            }

            if(order.getPayStatus() == 1){
                throw new BusinessException(ErrorCode.ORDER_ALREADY_PAIED, "账单已支付，不用重复支付。");
            }

            clientele = clienteleService.getById(order.getClienteleId());

            result = wechatPayService.prepare(clientele, openId, resType.codeOf(), order, useDeposit);
        }else if(resType == Const.RES_TYPE.PHOTOPRINT && StringUtils.isNotBlank(clienteleId)){
            clientele = clienteleService.getById(clienteleId);
            result = wechatPayService.prepare(clientele, openId, resType.codeOf(), resourceId, useDeposit);
        }

        if (result == null){
            return StatusResponse.error(ErrorCode.SIGN_ERROR, "支付失败");
        }

        return StatusResponse.success(result);
    }

    @RequestMapping(value = "/notifier",method = POST,
            consumes={MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE},
            produces={MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE})
    public  String wxPayNotifier(HttpServletRequest request,
                                   @RequestBody String requestXML) {

        Map<String, String> notifyMap = null;
        try {

            notifyMap = PaymentUtils.xml2Map(requestXML);
            log.info("微信支付回调:" + requestXML);
            log.info("微信支付回调:" + notifyMap);

            if (!wechatPayService.wxCheckSign(notifyMap)) {
                String ret = buildWxNotifyResult("FAIL", "check sign is failed");
                log.debug("return to wx server \n {}", ret);
                return ret;
            }

            return wechatPayService.processWXOrderResult(notifyMap, null);
        } catch (Exception e) {
            log.error("微信支付通知异常 requestMap:" + notifyMap, e);
            String ret = buildWxNotifyResult("FAIL", "Internal Server Error");
            log.debug("return to wx server \n {}", ret);
            return ret;
        }
    }

    @RequestMapping(value = "/order/check", method = POST)
    public Object wxOrderCheck(HttpServletRequest request,
                               Integer resourceType,
                               @RequestParam("outTradeNo") String outTradeNo) {

        String result = wechatPayService.wxOrderCheck(outTradeNo);
        if (org.apache.commons.lang3.StringUtils.isNotBlank(result)) {
            return StatusResponse.success();
        }

        return StatusResponse.error(ErrorCode.SIGN_ERROR, "支付失败");
    }

    private String buildWxNotifyResult(String resultCode, String resultMessage) {
        return "<xml><return_code><![CDATA[" + resultCode + "]]></return_code><return_msg><![CDATA[" + resultMessage + "]]></return_msg></xml>";
    }
}
